﻿#include "JPGReadWrite.h"

#include "Output/Console.h"
#include "File/FileUtils.h"
#include <stdio.h>
#include <jpeglib.h>

bool WH::ReadJPG(const SPath &InFilePath, TVector<uint8_t> &OutData, ETextureFormat &OutFormat, uint64_t &OutWidth, uint64_t &OutHeight, uint64_t &OutPitch)
{
    auto File=SFileUtils::ReadToBinary(InFilePath);


    jpeg_decompress_struct cinfo;
    jpeg_error_mgr jerr;
    
    cinfo.err = jpeg_std_error(&jerr);

    jpeg_create_decompress(&cinfo);
    //jpeg_stdio_src(&cinfo, File);
    jpeg_mem_src(&cinfo, File.Data(), File.Num());
    jpeg_read_header(&cinfo, TRUE);
    jpeg_start_decompress(&cinfo);

    OutWidth = cinfo.output_width;
    OutHeight = cinfo.output_height;

    //add extra alpha channel,because vulkan donot suport R8G8B8
    OutFormat = ETextureFormat::R8G8B8A8;
    OutPitch = OutWidth * 4;
    OutData.Resize(OutPitch * OutHeight);


    TVector<uint8_t> TempLine;
    TempLine.Resize(OutWidth * 3);

    uint8_t *pRow = TempLine.Data();
    
    while (cinfo.output_scanline < cinfo.output_height)
    {
        jpeg_read_scanlines(&cinfo, &pRow, 1);



        //复制到输出数据，需要上下翻转
        uint8_t *pPixel = pRow;
        //jpeg_read_scanline是已经读取的行数，所以需要减1
        uint8_t *pOutPixel = OutData.Data() + OutPitch * (cinfo.output_scanline-1);
        for (int i = 0; i < OutWidth; i++)
        {
            pOutPixel[0] = pPixel[0];
            pOutPixel[1] = pPixel[1];
            pOutPixel[2] = pPixel[2];
            pOutPixel[3] = 255;

            pPixel += 3;
            pOutPixel += 4;
        }
    }

    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
    
    return true;
}